﻿using Chaunce.FrameWork.NetCore.Chaunce.Utility.Helpers;
using Chaunce.FrameWork.NetCore.SysCore.Configuration;
using Chaunce.FrameWork.NetCore.SysCore.Infrastructure;
using Chaunce.Web.Core.Infrastructure;
using Chaunce.Web.Core.Infrastructure.Swagger;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.PlatformAbstractions;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Chaunce.Web.Core
{
    /// <summary>
    /// swagger 启动配置,默认包含 api,viewmodel,servicemodel对应的xml文件，如果需要增加可以继承改类重写GetXmlComments方法
    /// </summary>
    public class SwaggerStartup : IChaunceStartup
    {

        public int Order => 999;

        public void Configure(IApplicationBuilder application)
        {
            var hostingEnvironment = EngineContext.Current.Resolve<IHostingEnvironment>();
            if (!hostingEnvironment.IsDevelopment())
            {
                return;
            }
            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
            application.UseSwagger(c =>
            {
                c.RouteTemplate = "docs/{documentName}/docs.json";//使中间件服务生成Swagger作为JSON端点
                c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.Info.Description = httpReq.Path);//请求过滤处理
            });

            application.UseSwaggerUI(c =>
            {
                c.RoutePrefix = "docs";//设置文档首页根路径
                c.SwaggerEndpoint("/docs/v1/docs.json", "V1");//此处配置要和UseSwagger的RouteTemplate匹配
                c.InjectStylesheet("/swagger-ui/custom.css");//注入style文件
            });
        }

        public void ConfigureServices(IServiceCollection services, IConfigurationRoot configuration)
        {
            string title = "Chaunce Api";
            string description = "这是一个webapi接口文档说明";

            var swaggerDoc = services.BuildServiceProvider().GetRequiredService<ChaunceConfig>()?.SwaggerDoc;
            if (swaggerDoc != null)
            {
                if (!string.IsNullOrEmpty(swaggerDoc.Title))
                {
                    title = swaggerDoc.Title;
                }
                if (!string.IsNullOrEmpty(swaggerDoc.Descriptoin))
                {
                    description = swaggerDoc.Descriptoin;
                }
            }
            services.AddSwaggerGen(c =>
            {
                c.OperationFilter<SwaggerFileUploadFilter>();//增加文件过滤处理
                c.OperationFilter<SwaggerDefaultValueFilter>();//增加默认值
                c.OperationFilter<SwaggerRequiredFilter>();//必填字段标记
                var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, };
                c.AddSecurityRequirement(security);

                //批量找出swagger 需要关联的xml文件
                var basePath = PlatformServices.Default.Application.ApplicationBasePath;// 获取到应用程序的根路径
                List<string> xmlComments = GetXmlComments();
                xmlComments.ForEach(r =>
                {
                    string filePath = Path.Combine(basePath, r);
                    if (File.Exists(filePath))
                    {
                        c.IncludeXmlComments(filePath);
                    }
                });
          
                c.SwaggerDoc("v1", new Info
                {
                    Title = title,
                    Version = "v1",
                    Description = description,
                    TermsOfService = "None",
                    Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "Chaunce官网", Email = "info@Chaunce.com", Url = "http://www.Chaunce.com.cn/" },
                    License = new License
                    {
                        Name = "Swagger官网",
                        Url = "http://swagger.io/",
                    }
                });

                c.IgnoreObsoleteActions();
                c.AddSecurityDefinition("Bearer", new ApiKeyScheme
                {
                    Description = "权限认证(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
                    Name = "Authorization",
                    In = "header",
                    Type = "apiKey"
                });
            });
        }

        /// <summary>
        /// 设置swaager关联的xml文件名称(不包含路径，主要文件名称,如:Chaunce.XXX.Api.xml)
        /// </summary>
        /// <returns></returns>
        protected virtual List<string> GetXmlComments()
        {
            var pattern = "^Chaunce.*.(Api|ViewModel|ServiceModel)$";
            List<string> assemblyNames = ReflectionHelper.GetAssemblyNames(pattern);
            List<string> xmlFiles = new List<string>();
            assemblyNames.ForEach(r =>
            {
                string fileName = $"{r}.xml";
                xmlFiles.Add(fileName);
            });
            return xmlFiles;
        }

    }
}
